#ifndef DLL_SCRIPTCLASS_H
#define DLL_SCRIPTCLASS_H

#include "bbAddon.h"
#include "LinkedList.h"
#include "Tokenizer.h"

using namespace std;


int _Debug_COUNTcscriptObjs	= 0;
int _CLASS_ID = 0;


class cscriptClass;
class cscriptObj;
class cscriptField;


/* The scripting classes */

	/*
	; {
	;	@Last Instance pointer (Tail)	-	adress 4 bytes
	;	@First Instance pointer (Head)	-	adress 4 bytes
	;	%Count Instances				-	Integer 4 bytes
	;	%Count Fields					-	byte 1 byte
	;	@Classname						-	adress of String 4 bytes
	;	@Bank Field List				-	adress 4 bytes
	;	@Bank Field Names				-	adress 4 bytes
	; }
	*/

enum SCRIPT_TYPE
{
		SCRIPT_TYPE_INT,
		SCRIPT_TYPE_FLOAT,
		SCRIPT_TYPE_STRING,
		SCRIPT_TYPE_OBJECT
};


class cscriptClass
{

	friend class cscriptObj;
	friend class cscriptField;

private :
	
	cscriptObj* _head;
	cscriptObj* _tail;
	int _count;
	
	const char* _name;
	
	int _countfields;
	int* _fieldtypes;
	const char** _fieldnames;
	cscriptField* _ftail;
	cscriptField* _fhead;
	int _SizeOfFields;
	
	bool _build;
	bool _opened;
	cscriptClass* _next;
	cscriptClass* _prev;
	int _adress;
	
	inline bool _Build();
	
public :
	inline int EnterDef();

	cscriptClass();
	cscriptClass(const char* Name);
	~cscriptClass();
	
	/* Methods */
	inline void Unlink(cscriptObj* obj);
	inline cscriptObj* First(){return _head;};
	inline cscriptObj* Last(){return _tail;};
	inline const char* Name(){return _name;};
	inline cscriptClass* Find (const char* Name);
	inline int AdressOf(){return _adress;};
	
	
	friend inline int cscriptClassLeaveDef();
	friend inline int cscriptClassAddField(const char* signature);
};

cscriptClass* _NULL_CLASS	=	new cscriptClass();
cscriptClass* _CURDEF_CLASS	=	_NULL_CLASS;
cscriptClass* _HEAD_CLASS	=	_NULL_CLASS;
cscriptClass* _TAIL_CLASS	=	_NULL_CLASS;

/* Class Fields - Up to 255 Parameters
	; List of Type Identifier + Name (adress of string in Class String Bank as byte)
	;{
	;	%Type Identifier				-	byte 1 bytes
	;	%Class Identifier				-	int 4 bytes
	;										if (Class Identifier == CLASS_FIELD_TYPE_OBJ)
	;										(class identifier : value of '@PROTECTED_CClassInc' when class is created)
	;	%Size of Field					-	Integer 4 bytes
	;	%Pointer to Name Field			-	bank offset 4 bytes
	;	%Offset of attribute in instance-	integer 4 bytes
	;}
	*/

/* Fields of class */
class cscriptField
{
	friend class cscriptClass;
	friend class cscriptObj;
public :
	cscriptField();
	~cscriptField();
	
	cscriptClass* _class;
	cscriptField* _next;
	cscriptField* _prev;

	int _typedef;
	const char* _name;
};
cscriptField* _NULL_FIELD	=	new cscriptField();

/* instances of class */

	/*
	;{
	;	@Class							-	adress 4 bytes
	;	@Next Instance					-	adress 4 bytes
	;	@Prev Instance					-	adress 4 bytes
	;	... Datas						-	Size of Fields
	;}
	*/

class cscriptObj
{
	friend class cscriptClass;
	friend class cscriptField;
private :
	cscriptClass* _class;
	const char* _data;
	cscriptObj* _next;
	cscriptObj* _prev;
	
	int _adress;
	/* Method to Detach the instance */
	inline void cscriptObj::_Unlink(){_class->Unlink(this);};

public:
	/* Constructor/Destructor */
	cscriptObj();
	~cscriptObj();
	cscriptObj(cscriptClass*Class);
	
	/* Global Linked List */
	inline cscriptObj* After(){return _next;};
	inline cscriptObj* Before(){return _prev;};
	
	inline cscriptObj* After(const cscriptObj*Obj){return Obj->_next;};
	inline cscriptObj* Before(const cscriptObj*Obj){return Obj->_prev;};
	
	void Insert(cscriptObj*Obj);
	inline void Insert(cscriptObj*Obj,cscriptObj*Before)
	{
		Obj->Insert(Before);
	};
	
	
	// Properties/Attributes
	inline void Set(const char* Datas, const int FieldID);
	inline const char* Get(const int FieldID);

	inline int AdressOf(){return _adress;}
};

cscriptObj* _NULL_cscriptObj=new cscriptObj();











/*
; - Type Identifier -
	Const CLASS_FIELD_TYPE_BYT%			=	1
	Const CLASS_FIELD_TYPE_SHT%			=	2
	Const CLASS_FIELD_TYPE_INT%			=	3
	Const CLASS_FIELD_TYPE_FLT%			=	4
	Const CLASS_FIELD_TYPE_STR%			=	5
	Const CLASS_FIELD_TYPE_OBJ%			=	6
	Const CLASS_FIELD_TYPE_ARR%			=	7

; End of declaration symbol
	Const CLASS_FIELD_SYMBOL_BYT$		=	"&"
	Const CLASS_FIELD_SYMBOL_SHT$		=	"!"
	Const CLASS_FIELD_SYMBOL_INT$		=	"%"
	Const CLASS_FIELD_SYMBOL_FLT$		=	"#"
	Const CLASS_FIELD_SYMBOL_STR$		=	"$"
	Const CLASS_FIELD_SYMBOL_OBJ$		=	"*"
	Const CLASS_FIELD_SYMBOL_ARR$		=	"]"
	
	Const CLASS_FIELD_SYMBOL_ARRSTART$	=	"["

; - Class Constructor -
; End with EndCClass
; eg :
;    MyClass = CClass()
;        cField "anInt%"
;        cField "aFloat#"
;        cField "aString$"
;        cField "aCObject*"
;        cField "aCollection["+ofFixedSize%+"]"
;    EndCClass

*/

#endif //DLL_SCRIPTCLASS_H